<template>
    <el-dialog title="添加弹窗" :visible.sync="visible" width="400px" @open="onDialogOpen" @close="onDialogClose"
        :before-close="handleBeforeClose">
        <div>
            <p>弹窗内容：</p>
            <div v-if="loading" style="text-align:center; padding: 20px;">
                <el-spin tip="加载中..." />
            </div>
            <div v-else ref="dialogSelectContainer"></div>
        </div>
        <template #footer>
            <el-button @click="visible = false">取消</el-button>
            <el-button type="primary" @click="onConfirm" :disabled="loading">确定</el-button>
        </template>
    </el-dialog>
</template>

<script setup>
import { ref, watch, nextTick } from 'vue'

const props = defineProps({
    visible: Boolean,
    loading: Boolean,
})

const emit = defineEmits(['update:visible', 'confirm'])

const dialogSelectContainer = ref(null)
const selectContainer = ref(null) // 这里会通过 expose 传入

// 通过 expose 接收主页面传入的 select 容器引用
defineExpose({
    setSelectContainer(container) {
        selectContainer.value = container
    },
})

function onDialogOpen() {
    nextTick(() => {
        if (!selectContainer.value || !dialogSelectContainer.value) return

        const selectEl = selectContainer.value.firstElementChild
        if (!selectEl) return

        if (dialogSelectContainer.value.contains(selectEl)) return

        dialogSelectContainer.value.appendChild(selectEl)
    })
}

function onDialogClose() {
    nextTick(() => {
        if (!selectContainer.value || !dialogSelectContainer.value) return

        const selectEl = dialogSelectContainer.value.firstElementChild
        if (!selectEl) return

        if (selectContainer.value.contains(selectEl)) return

        selectContainer.value.appendChild(selectEl)
    })
}

function handleBeforeClose(done) {
    onDialogClose()
    done()
}

function onConfirm() {
    emit('confirm')
    emit('update:visible', false)
}

// 监听 visible 变化，方便外部控制
watch(
    () => props.visible,
    (newVal) => {
        if (!newVal) {
            onDialogClose()
        }
    }
)
</script>
